#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <openssl/rand.h>


static int display = 0;

struct format{
  int number_cycle;
};

struct rec{
  double x,y,z;
};

int rdtsc()
{
    __asm__ __volatile__("rdtsc");
}


int func_read(char * fichier){
  struct rec myRecord;
  struct format myFormat;
  FILE *file;
  int counter=0;

  file = fopen(fichier,"r");
  if (!file){
    perror("file");
    return -1;
  }
  // Lecture de l'entête du fichier
  fread(&myFormat, sizeof(struct format), 1, file);
  printf("Nombre d'enregistrements: %i\n", myFormat.number_cycle);

  for (counter=1;counter<=myFormat.number_cycle;counter++){
    fread(&myRecord,sizeof(struct rec),1,file);
    if (display == 1){
      printf("x=%f, y=%f, z=%f\n", myRecord.x, myRecord.y, myRecord.z);
    }
  }
  fclose(file);

  return 0;
}

int func_write(char * fichier, int nb_cycles){
  struct rec myRecord;
  struct format myFormat;
  FILE *file;
  int counter=0;

  file = fopen(fichier,"w");
  if (!file){
    perror("file");
    return -1;
  }
  myFormat.number_cycle = nb_cycles;

  //Ecriture de l'entête du fichier
  fwrite(&myFormat,sizeof(struct format),1,file);

  for (counter=1;counter<=myFormat.number_cycle ;counter++){
    srand(rdtsc());
    myRecord.x = rand();
    srand(rdtsc());
    myRecord.y = rand();
    srand(rdtsc());
    myRecord.z = rand();
    if (display) {printf("number=%i (x=%f, y=%f, z=%f)\n",counter, myRecord.x, myRecord.y, myRecord.z);}
    fwrite(&myRecord,sizeof(struct rec),1,file);
  }
  fclose(file);
 
  return 0;
}

void func_help(){
  fprintf(stderr,"Utilisation\n");
  fprintf(stderr,"main [-r FILE | -w FILE]\n");
  fprintf(stderr,"-r FILE:\tRead a binary file\n");
  fprintf(stderr,"-w FILE:\tWrite a binary file\n");
  fprintf(stderr,"-n NUMBER:\tNumber of cyle to write (default 10)\n");
  fprintf(stderr,"-d :\tDisplay lines\n");
  return;
}

int main(int argc, char **argv){
  char format[] = "hdr:w:n:";
  int optch;
  extern int opterr;
  int nb_cycles=10;

  opterr = 1;

  while((optch = getopt(argc, argv, format)) != -1)
    switch(optch) {
      case 'r':
        func_read(optarg);
        break;
      case 'w':
        func_write(optarg,nb_cycles);
        break; 
      case 'n':
        nb_cycles = strtod(optarg, NULL);
        break;
      case 'h':
        func_help();
        break;
      case 'd':
        display = 1;
        break;
      default:
        func_help();
    }
}
